home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
answrbok
/
4_6.lha
/
4_6
/
4_6c.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-08
|
3KB
|
126 lines
* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
* The C++ Answer Book */
* Tony Hansen */
* All rights reserved. */
/ quick sort
/ Version 3
/ Based on "Algorithms" by Robert Sedgewick
/ Chapter 9, pp 103-113
include <swap.h>
/ Global variables
tatic char *a;
tatic int size;
tatic int (*cmpfn)(const void*,const void*);
onst int unitcutoff = 16;
tatic int cutoff;
/ internal function to swap two
/ elements of the array
nline void swapelem(char *ax, char *ay)
for (int i = size; i-- > 0; )
swap(*ax++, *ay++);
include <string.h>
/ insertion sort to finish the job off
tatic void inssort(int left, int right)
char *savearea = new char[size];
for (int i = left + size; i <= right; i += size)
{
memcpy(savearea, &a[i], size);
for (int j = i, k = j - size;
j > 0 && (*cmpfn)(&a[k], savearea) > 0;
j -= size, k -= size)
memcpy(&a[j], &a[k], size);
memcpy(&a[j], savearea, size);
}
delete savearea;
/ partition the array into two halves
/ after the partition,
/ K[left] < ... < K[i] < ... < K[right]
/ iqsort will then recursively sort
/ K[left] through K[i-1] and
/ K[i+1] through K[right]
tatic int partition(int left, int right)
// sort-three: sort left, middle and right elements
// to find partitioning element
int mid = (left + right) / size / 2 * size;
if ((*cmpfn)(&a[left], &a[mid]) > 0)
swapelem(&a[left], &a[mid]);
if ((*cmpfn)(&a[left], &a[right]) > 0)
swapelem(&a[left], &a[right]);
if ((*cmpfn)(&a[mid], &a[right]) > 0)
swapelem(&a[mid], &a[right]);
int j = right - size;
swapelem(&a[mid], &a[j]);
int i = left;
char* v = &a[j];
do {
do {
i += size;
} while ((*cmpfn)(&a[i], v) < 0);
do {
j -= size;
} while ((*cmpfn)(&a[j], v) > 0);
swapelem(&a[i], &a[j]);
} while (i < j);
swapelem(&a[j], &a[i]);
swapelem(&a[i], &a[right - size]);
return i;
/ the secondary routine which will
/ do the actual sorting
tatic void iqsort(int left, int right)
while (right - left > cutoff)
{
int i = partition(left, right);
if (i - left > right - i)
{
iqsort(i + size, right);
right = i - size;
}
else
{
iqsort(left, i - size);
left = i + size;
}
}
oid qsort3(void *array, unsigned nel,
unsigned sz,
int (*cmpfunc)(const void*,const void*))
a = (char*)array; // set global variables
size = sz;
cmpfn = cmpfunc;
cutoff = sz * unitcutoff;
int endindex = (nel - 1) * size;
iqsort(0, endindex);
inssort(0, endindex);